home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
util2
/
mergerec.lha
/
MergeRec
/
MergeRec.e
< prev
Wrap
Text File
|
1995-12-06
|
7KB
|
242 lines
/*
MergeRec v1.1 - 5 Dec 95
Keeps your local copy of the Aminet INDEX file up to date by incorporating
changes from RECENT.
Usage: MergeRec INDEXFILE/A,RECENTFILE/A,OUTPUT
INDEXFILE: the local copy of an Aminet info/index/INDEX file.
WARNING: The regular INDEX file (pub/aminet/INDEX) will
NOT work! Use the file pub/aminet/info/index/INDEX because
it contains a 'weeks old' column.
RECENTFILE: an Aminet RECENT file, either downloaded from an Aminet Site
or received by e-mail from wuarchive listserver.
OUTPUT: Filename of the new index file. If no filename is given,
standard output is used.
Original program by Alex Tucker (alex@warp.demon.co.uk)
(Aminet: text/misc/MergeRecent.lha)
Rewritten in AmigaE and modified by Adriano De Minicis (mc4948@mclink.it)
Compiled with AmigaE v3.2e
*/
OPT OSVERSION=37
MODULE 'dos','dos/dos','dos/datetime','utility'
CONST MAXLEN=200
ENUM OK, ER_MEM, ER_BADARGS, ER_UTIL, ER_OPEN, -> Error codes
ER_SHORT, ER_DATE, ER_BREAK -> Error codes
RAISE ER_BREAK IF CtrlC()=TRUE, -> Set common exceptions
ER_MEM IF String()=NIL
OBJECT date
days: LONG
str[40]: ARRAY OF CHAR
ENDOBJECT
DEF ifh, rfh, ofh, -> filehandles
line[MAXLEN]:STRING, t[MAXLEN]:STRING, -> line buffers
recdate:date, indexdate:date, -> file dates
wd, not_eof, id=0, reclist=NIL -> misc
/* Main */
PROC main() HANDLE
DEF args:PTR TO LONG, rdargs, templ, output
templ:='INDEXFILE/A,RECENTFILE/A,OUTPUT'
args:=[0,0,0]
IF (rdargs:=ReadArgs(templ,args,NIL))=NIL THEN Raise(ER_BADARGS)
IF (utilitybase:=OpenLibrary('utility.library',37))=NIL THEN Raise(ER_UTIL)
IF (ifh:=Open(args[0],OLDFILE))=NIL THEN Throw(ER_OPEN,0)
IF (rfh:=Open(args[1],OLDFILE))=NIL THEN Throw(ER_OPEN,1)
ofh:=IF args[2]=NIL THEN stdout ELSE Open(args[2],NEWFILE)
IF ofh=NIL THEN Throw(ER_OPEN,2)
output:=(ofh<>stdout)
/* Read RECENT, and build the list */
IF output THEN WriteF('Reading and sorting recent file list...\n')
read_recent()
/* Get first line of INDEX */
not_eof:=Fgets(ifh,line,MAXLEN)
getdate(line,indexdate)
IF (recdate.days-indexdate.days)>7 THEN WriteF('\nWARNING: Index file is more than a week older than recent file\n\n')
wd:=(recdate.days-indexdate.days)/7 -> difference in weeks between RECENT and INDEX
/* Write new INDEX header */
StringF(t,'| Updated Aminet Index on \s\n',recdate.str)
Fputs(ofh,t)
/* If original INDEX file then save its creation date */
IF StrCmp(line,'| Updated Aminet Index',STRLEN)=FALSE
StringF(t,'| Original Index date: \s\n',indexdate.str)
Fputs(ofh,t)
ENDIF
/* Skip header lines */
not_eof:=Fgets(ifh,line,MAXLEN)
WHILE not_eof AND (line[0]="|")
Fputs(ofh,line)
not_eof:=Fgets(ifh,line,MAXLEN)
ENDWHILE
/* Merging lists */
IF output THEN WriteF('Merging lists...\n')
merge()
IF output AND (id>0) THEN WriteF('\d identical filename\s updated.\n',id, IF id=1 THEN '' ELSE 's')
Raise(OK)
EXCEPT
/* Program cleanup and error handling */
IF ifh THEN Close(ifh)
IF rfh THEN Close(rfh)
IF ofh<>stdout THEN Close(ofh)
IF utilitybase THEN CloseLibrary(utilitybase)
IF rdargs THEN FreeArgs(rdargs)
IF reclist THEN DisposeLink(reclist)
SELECT exception
CASE ER_MEM; WriteF('Not enough memory\n')
CASE ER_BADARGS; PrintFault(IoErr(), NIL)
CASE ER_UTIL; WriteF('Can''t open utility.library\n')
CASE ER_OPEN; WriteF('Can''t open "\s"\n',args[exceptioninfo])
CASE ER_DATE; WriteF('Unable to read valid date\n')
CASE ER_SHORT; WriteF('Premature end of file in \s\n',args[1])
CASE ER_BREAK; WriteF('** User Break\n')
ENDSELECT
ENDPROC
/* Read the RECENT files and sort it */
PROC read_recent()
DEF s, curr, prev, found, dircmp, filecmp, len
not_eof:=Fgets(rfh,line,MAXLEN)
/* Search header start */
WHILE not_eof AND (StrCmp(line,'| Recent uploads to',STRLEN)=FALSE)
not_eof:=Fgets(rfh,line,MAXLEN)
ENDWHILE
getdate(line,recdate)
WHILE not_eof AND (line[0]="|")
not_eof:=Fgets(rfh,line,MAXLEN) -> Skip header
ENDWHILE
IF not_eof=FALSE THEN Raise(ER_SHORT) -> File too short!
WHILE not_eof AND (line[0]<>"|") -> Do until EOF or another header
/* Convert CR-LF (if present) to LF */
len:=StrLen(line)
IF (len>1) AND (line[len-2]="\b")
line[len-2]:="\n"
line[len-1]:="\0"
SetStr(line,len-1) -> Adjust the internal lenght
ENDIF
/* Sort */
prev:=reclist
curr:=Next(prev)
found:=FALSE
IF line[0]<>"\n" -> Sort "line" in the recent list
WHILE (curr<>NIL) AND Not(found)
dircmp:=Strnicmp(curr+19,line+19,10) -> dircmp>0 if line.dir<curr.dir
filecmp:=Strnicmp(curr,line,18) -> filecmp>0 if line.file<curr.file
IF ((dircmp=0) AND (filecmp>0)) OR (dircmp>0)
found:=TRUE
ELSE
prev:=curr
curr:=Next(curr)
ENDIF
ENDWHILE
s:=String(StrLen(line)) -> Alloc memory for the string
StrCopy(s,line,ALL) -> Copy current line
IF prev THEN Link(prev,s) ELSE reclist:=s
Link(s,curr)
ENDIF
not_eof:=Fgets(rfh,line,MAXLEN) -> Get next line
CtrlC() -> Check user abort
ENDWHILE
ENDPROC
/* Extract date from the end of the string 's' */
PROC getdate(s,d:PTR TO date)
DEF i, dt:datetime
StrCopy(t,s) -> Work on a backup copy
i:=StrLen(t)-1
IF t[i-1]="\b" THEN DEC i -> Remove carriage returns
t[i]:="\0" -> Remove \n at the end of the line.
IF i>4 AND t[i-3]<>"-" -> If year has more than two digits, remove
t[i-4]:=t[i-2] -> the first two (otherwise the Dos function
t[i-3]:=t[i-1] -> 'StrToDate' doesn't work).
t[i-2]:="\0"
ENDIF
WHILE i>=0 AND t[i]<>" " DO DEC i -> Search start of date string
AstrCopy(d.str,t+i+1,40) -> Copy the date string
dt.format:=FORMAT_DOS
dt.flags:=0
dt.strdate:=d.str
dt.strtime:=NIL
IF StrToDate(dt)=FALSE THEN Raise(ER_DATE) -> Convert into days
d.days:=dt.stamp.days
ENDPROC
/* Merge INDEX file with the recent list */
PROC merge()
DEF curr, dircmp, filecmp
curr:=reclist
WHILE not_eof
IF curr
dircmp:=Strnicmp(line+19,curr+19,10) -> dircmp>0 if line.dir>curr.dir
filecmp:=Strnicmp(line,curr,18) -> filecmp>0 if line.file>curr.file
IF (dircmp>0) OR ((dircmp=0) AND (filecmp>=0))
StringF(t,'\s[34] 0\s',curr,curr+34)
Fputs(ofh,t) -> insert 'curr' before 'line'
IF filecmp=0
INC id -> duplicated line
not_eof:=Fgets(ifh,line,MAXLEN) -> get next line from index
ENDIF
curr:=Next(curr)
ELSE -> copy 'line' and update the age column
copyline()
ENDIF
ELSE -> copy 'line' and update the age column
copyline()
ENDIF
CtrlC()
ENDWHILE
WHILE curr
StringF(t,'\s[34] 0\s',curr,curr+34)
Fputs(ofh,t)
curr:=Next(curr)
CtrlC()
ENDWHILE
ENDPROC
/* copy INDEX line to OUTPUT, updating the age column */
PROC copyline()
DEF i
IF wd>0
StringF(t,'\d[4]',Val(line+34)+wd)
FOR i:=0 TO 3 DO line[34+i]:=t[i]
ENDIF
Fputs(ofh,line)
not_eof:=Fgets(ifh,line,MAXLEN)
ENDPROC